using System;
using System.Xml.Linq;

using Mono.Addins;

namespace Gazebo.Core
{
    public sealed class CorePreferences : PreferenceContainer
    {
        public static readonly CorePreferences Instance = new CorePreferences();
        
        private string serverHostname;
        
        [Preference("ServerHostname", "freechess.org")]
        public string ServerHostname {
            get {
                return serverHostname;
            }
            set {
                if (value == null) {
                    throw new ArgumentNullException();
                }
                
                value = value.Trim();
                if (value == "") {
                    throw new ArgumentException("value: Is empty or whitespace.");
                }
                
                serverHostname = value;
            }
        }
        
        private int serverPort;
        
        [Preference("ServerPort", (int) 5000)]
        public int ServerPort {
            get {
                return serverPort;
            }
            set {
                if (value < 0 || value > ushort.MaxValue) {
                    throw new ArgumentOutOfRangeException("value: Must be between 0 and 65535");
                }
                
                serverPort = value;
            }
        }
        
        [Preference("NetworkFilterType", "Gazebo.Timeseal.Timeseal2Factory")]
        private string networkFilterTypeName;
        
        public INetworkFilterFactory NetworkFilterFactory { get; set; }
        
        [Preference("PlaySounds", true)]
        public bool PlaySounds { get; set; }
        
    	private CorePreferences()
        {
        }
		
    	protected override XElement GetContainerRoot()
        {
            return PreferencesManager.GlobalManager.GetAddinPreferences("Gazebo.Core");
        }
        
        protected override void OnSave ()
        {
            networkFilterTypeName = NetworkFilterFactory == null ? "" :
                NetworkFilterFactory.GetType().FullName;
        }
        
        protected override void OnLoadCompleted ()
        {
            NetworkFilterFactory = null;
            
            if (networkFilterTypeName == null) {
                return;
            }
            
            var factories = AddinUtilities.GetExtensionObjects<INetworkFilterFactory>("/Gazebo/Client/NetworkFilter");
            
            foreach (INetworkFilterFactory factory in factories) {
                if (factory.GetType().FullName == networkFilterTypeName) {
                    NetworkFilterFactory = factory;
                    break;
                }
            }
        }
	}
}
